package com.zongtui.fourinone.base;

import com.zongtui.fourinone.base.config.ConfigContext;
import com.zongtui.fourinone.park.ParkActive;
import com.zongtui.fourinone.utils.log.LogUtil;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
 * 基础对象服务.【继承线程池功能】.
 */
public class BeanService extends PoolExector {

    /**
     * 设置基础对象值.【并且注册远程对象】
     *
     * @param remoteHostName 远程服务域名
     * @param remoteLogCalls 远程日志调用
     * @param remotePort     远程端口号
     * @param remoteName     服务名称
     * @param parkObject     服务对象
     */
    public static void putBean(String remoteHostName, boolean remoteLogCalls, int remotePort, String remoteName, ParkActive parkObject) {
        if (remoteHostName != null) {
            //设置端口号
            System.setProperty(ConfigContext.getRemoteHostName(), remoteHostName);
        }
        if (remoteLogCalls) {
            //设置日志调用.
            System.setProperty(ConfigContext.getLogCalls(), "true");
        }
        try {
            //注册远程对象.
            LocateRegistry.getRegistry(remotePort).list();
        } catch (Exception ex) {
            try {
                //出现异常，重新绑定.

                //导出该远程对象.
                UnicastRemoteObject.exportObject(parkObject, 0);
                //创建注册
                Registry rgsty = LocateRegistry.createRegistry(remotePort);//getRegistry(TPYDK);
                //重新绑定
                rgsty.rebind(remoteName, parkObject);
            } catch (Exception e) {
                LogUtil.info("[ObjectService]", "[regObject]", "[Error Exception:]", e);
//                e.printStackTrace();
            }
        }
    }

    /**
     * 设置基础对象值.【并且注册远程对象，附带安全策略】
     *
     * @param remoteHostName  远程服务域名
     * @param remoteLogCalls  远程日志调用
     * @param remotePort      远程端口号
     * @param remoteName      服务名称
     * @param parkObject      服务对象
     * @param codebase        codebase参数
     * @param policy          安全策略
     * @param securityManager 安全管理
     */
    public static void putBean(String remoteHostName, boolean remoteLogCalls, int remotePort, String remoteName, ParkActive parkObject, String codebase, String policy, SecurityManager securityManager) {
        //设置security
        setSecurity(codebase, policy, securityManager);
        //注册远程对象
        putBean(remoteHostName, remoteLogCalls, remotePort, remoteName, parkObject);
    }

    /**
     * @param remoteHostName 远程服务域名
     * @param remotePort     远程服务端口
     * @param remoteName     服务名称
     * @return 当前活动的远程对象.
     * @throws RemoteException
     */
    public static ParkActive getBean(String remoteHostName, int remotePort, String remoteName) throws RemoteException {
        try {
            //设置传输超时时间.
            if (ConfigContext.getWorkerTimeout() > 0l)
                System.setProperty(ConfigContext.getTransportTimeout(), ConfigContext.getWorkerTimeout() + "");
            //获得DataServer对象，进行方法调用.
            return (ParkActive) Naming.lookup(ConfigContext.getProtocolInfo(remoteHostName, remotePort, remoteName));
        } catch (Exception e) {
            //LogUtil.info("[BeanService]", "[getBean]", "getBean:"+e.getClass());
            if (e instanceof RemoteException)
                throw (RemoteException) e;
            else {
                //e.printStackTrace();
                LogUtil.info("[ObjectService]", "[getBean]", "[Error Exception:]", e);
            }
        }
        return null;
    }

    /**
     * 设置安全属性.
     *
     * @param codebase        codebase参数
     * @param policy          安全策略
     * @param securityManager 安全管理
     */
    private static void setSecurity(String codebase, String policy, SecurityManager securityManager) {
        if (codebase != null && policy != null) {
            System.setProperty(ConfigContext.getRemoteCodebase(), codebase);
            System.setProperty(ConfigContext.getSecurityPolicy(), policy);
            if (System.getSecurityManager() == null && securityManager != null) {
                //ParkManager()
                System.setSecurityManager(securityManager);
            }
        }
    }
}